package com.yc.spring.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Aspect
public class MyAspect {
    long begin;
//    @Before("execution(public void com.yc.spring.mapper.UserMapper.init(int a))")
    //上面是完整的 下面用..和* ..代表着这个之后的目录 *代表着这个目录下的任意一个
    @Before("execution(* com.yc..*Mapper.*(..))")
    //直接用方法参数注入对象=》接口注入
    public void before(JoinPoint joinPoint) {
        begin = System.currentTimeMillis();
        System.out.println("方法签名 joinPoint.getSignature() = " + joinPoint.getSignature());
        System.out.println("参数数组 joinPoint.getArgs() = " + Arrays.toString(joinPoint.getArgs()));
        System.out.println(".............前置拦截...........");
    }
    //切点方法
    @Pointcut("execution(* com.yc..*Mapper.*(..))")
    public void myPointCut(){

    }
    @After("myPointCut()")
    public void after(JoinPoint joinPoint){
        System.out.println("............后置拦截.............");
    }
    @AfterReturning(value = "myPointCut()",returning = "ret")
    public void afertReturning(Object ret){
        //可以获取业务的返回值
        System.out.println("业务的返回值"+ret);
        System.out.println("............返回拦截.............");
    }
    @AfterThrowing(value = "myPointCut()",throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Throwable ex){
        System.out.println("业务方法的异常 ret="+ex);
        System.out.println(".............异常拦截.............");
    }
    @Around("myPointCut()")
    public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
        //环绕增强是手动执行
        try {
            System.out.println("------------环绕增强：前置-----------------");
            long begin=System.currentTimeMillis();
            Object ret=joinPoint.proceed();
            long end=System.currentTimeMillis();
            System.out.println("共耗时"+(end-begin)+"毫秒");
            System.out.println("环绕增强：返回------------------");
            //环绕增强的返回值=》业务方法的返回值
            return ret;
        }catch (Throwable e){
            System.out.println("------------环绕增强:异常------------");
            throw new RuntimeException("业务方法出现异常"+e);
        }finally {
            System.out.println("----------------环绕增强：后置-------------------");
        }
    }
}
